﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Linq;
using System.Text;
using System.Data.Entity;
using Gqq.CodeFirst.Palace;

namespace Gqq.CodeFirst.ProcessPalace
{
    public class Part7 : PartBase
    {
        public static void DoTest()
        {
            TestRemove();
        }

        #region Using Local to look at local data
        /// <summary>
        /// Using Local to look at local data
        /// Local表示当时数据库的变化。不会影响数据库。
        /// 1、新的Unicorn（Linqy）没有存入数据库中，但是在Local中。Linqy的主key为0，主要是还没有形成一个真实的主key
        /// 2、id为6的unicorn没有包含在Local中，因为其状态为Deleted
        /// 3、DbSet中的值是对数据库的客观反映。所以不包含Linqy
        /// </summary>
        public static void TestLocal()
        {

            // Load all unicorns from the database into the context
            db.Unicorns.Load();
            // Add a new unicorn to the context
            db.Unicorns.Add(new Unicorn { Name = "Linqy" });

            db.Unicorns.Remove(db.Unicorns.Find(6));

            // Loop over the unicorns in the context.
            Console.WriteLine("In Local: ");
            foreach (Unicorn unicorn in db.Unicorns)
            {
                Console.WriteLine("Found {0}: {1} with state {2}",
                                  unicorn.Id, unicorn.Name, db.Entry(unicorn).State);
            }


            // Perform a query against the database.
            Console.WriteLine("\nIn DbSet query: ");
            foreach (Unicorn unicorn in db.Unicorns.Local)
            {
                Console.WriteLine("Found {0}: {1} with state {2}",
                                 unicorn.Id, unicorn.Name, db.Entry(unicorn).State);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static void TestLocal2()
        {
            db.Unicorns.Where(x => x.Id == 5).Load();
            foreach (Unicorn unicorn in db.Unicorns.Local)
            {
                Console.WriteLine(unicorn.Name);
            }
            Console.WriteLine();

            db.Unicorns.Where(x => x.Id == 6).Load();
            foreach (Unicorn unicorn in db.Unicorns.Local)
            {
                Console.WriteLine(unicorn.Name);
            }
            Console.WriteLine();


        }

        public static void TestRemove()
        {
            db.Unicorns.Load();
            db.Unicorns.Local.Remove(db.Unicorns.Local.FirstOrDefault(x => x.Id == 5));

            var removed = db.Unicorns.Find(5);

            //输出Deleted
            Console.WriteLine(db.Entry(removed).State);
        }

        #endregion





        /// <summary>
        /// 不同的查询可以更新Local
        /// 1、Linqy被加入到Local Collection中去，并且变为Added状态。如果调用了savechanges方法
        /// 则会更新到数据库中去。
        /// 2、Id为5的数据在Local collection中被删除。
        /// 3、在之后查询的数据，就会加入到Local Collection中去。
        /// ObservableCollection不能有大量的数据。因此有几千条数据及以上，建议不要使用Local
        /// </summary>
        public static void TestAddRemoveLocal()
        {
            db.Unicorns.Where(x => x.Name.StartsWith("B")).Load();

            //特别注意，如果用了下面的一段话，整个Local就会变化
//            foreach (Unicorn unicorn in db.Unicorns)
//            {
//                Console.WriteLine("Found {0}: {1} with state {2}",
//                                 unicorn.Id, unicorn.Name, db.Entry(unicorn).State);
//            }
            var local = db.Unicorns.Local;
            local.Add(new Unicorn {Name = "Linqy"});
            local.Remove(db.Unicorns.Find(5));
            foreach (Unicorn unicorn in db.Unicorns.Local)
            {
                Console.WriteLine("Found {0}: {1} with state {2}",
                                 unicorn.Id, unicorn.Name, db.Entry(unicorn).State);
            }

            // Query some more unicorns from the database
            db.Unicorns.Where(u => u.Name.EndsWith("py")).Load();

            // Loop over the unicorns in the context again.
            Console.WriteLine("\nIn Local after query: ");
            foreach (var unicorn in db.Unicorns.Local)
            {
                Console.WriteLine("Found {0}: {1} with state {2}",
                                  unicorn.Id, unicorn.Name,
                                  db.Entry(unicorn).State);
            }
        }

        public static void TestTrackEntities()
        {
//            var str = "test";
//
////            var princess = db.Princesses.FirstOrDefault();
//            var princess = db.Princesses.FirstOrDefault();
//            db.Princesses.Add(new Princess() {Name = "ddd"});
//            db.Princesses.Local.First().Name = "Modified";
//
//            //一开始，当Princess没有改变的时候，这个是空的。
//            foreach (DbEntityEntry<Princess> entry in db.ChangeTracker.Entries<Princess>())
//            {
//                object oriId = entry.State == EntityState.Added ? (object) "Null" : entry.Property(x => x.Id).OriginalValue;
//                object oriName = entry.State == EntityState.Added ? "Null" : entry.Property(x => x.Name).OriginalValue;
//                Console.WriteLine("Found entity of type {0} with state {1},princess's id:{2}-{3}, name:{4}-{5}",
//                                  ObjectContext.GetObjectType(entry.Entity.GetType()),
//                                  entry.State, entry.Property(x => x.Id).CurrentValue, oriId
//                                  , entry.Property(x => x.Name).CurrentValue, oriName);
//            }
//
//            Console.WriteLine("princess local");
//            //在princess没有取得任何数据的同事，local中的数据是空的。
////            db.Princesses.Load();
//            foreach (var local in db.Princesses.Local)
//            {
//                Console.WriteLine("princess id:{0},name:{1}", local.Id, local.Name);
//            }

            //有这个Load和没有这个Load是完全不一样的。有了Load，表示全部查询出所有的数据。
//            db.Unicorns.Load();
            // Load some entities into the context
            db.Unicorns.Include(u => u.Princess.LadiesInWaiting).Load();
            //通过这个方法可以测试出，local的princess只是unicorns中拥有的princess。
            //unicorns中没有的princess是不会出来的。
            foreach (var p in db.Princesses.Local)
            {
                Console.WriteLine(p.Name);
            }
            db.Unicorns.Add(new Unicorn {Name = "Linqy"});
            db.Unicorns.Remove(db.Unicorns.Find(5));
            foreach (DbEntityEntry<Unicorn> entry in db.ChangeTracker.Entries<Unicorn>())
            {
                Console.WriteLine(entry.Property(x => x.Name).CurrentValue);
                Console.WriteLine("Found entity of type {0} with state {1}",
                  ObjectContext.GetObjectType(entry.Entity.GetType()).Name,
                  entry.State);
            }

            Console.WriteLine("\n princess change info");
            //根据db.ChangeTracker，我们可以很容易找到某个对象的变化过程。根据这些对象的变化过程。
            //我们可以做一些自己的事情。
            var firstOrDefault = db.Princesses.Local.FirstOrDefault(x => x.Id == 13);
            if (firstOrDefault != null) firstOrDefault.Name = "Sleeping Beauty2";
            foreach (var entry in db.ChangeTracker.Entries<Princess>())
            {
                Console.WriteLine(entry.Property(x => x.Name).CurrentValue);
                Console.WriteLine("Found entity of type {0} with state {1}",
                  ObjectContext.GetObjectType(entry.Entity.GetType()).Name,
                  entry.State);
            }

        }
    }
}
